<template>
  <el-upload
    ref="upload"
    v-model:file-list="fileList"
    :action="uploadImgUrl"
    :headers="headers"
    :limit="1"
    :show-file-list="false"
    :on-exceed="handleExceed"
    :on-change="handleChange"
    :before-upload="handleBeforeUpload"
    :on-success="handleSuccess"
    :on-error="handleError"
  >
    <div class="upload-image borderImg" style="margin-left: 0px;" v-for="(item, index) in chooseFileList" :key="index" v-if="chooseFileList.length">
      <img :src="item.url" style="width: 100%;height: 100%;">
      <div class="loadingBox pageFlex pageFlexCenter" v-if="chooseFileList[0].loading">
        <div>上传中~</div>
      </div>
      <label class="successBox pageFlex pageFlexCenter" v-if="fileList[0] && fileList[0].status && fileList[0].status == 'success'">
        <el-icon style="transform: rotate(-45deg);margin-top: 20%;"><Check /></el-icon>
      </label>
    </div>
    <div class="pageFlexColumn pageFlexCenter upload-image" :style="{backgroundColor: bg}" v-else>
      <el-icon class="avatar-uploader-icon"><plus /></el-icon>
      <div class="text">{{ imgText }}</div>
    </div>
    <template #tip v-if="showTip">
      <div class="el-upload__tip text-red">1.只上传一张图片</div>
      <div class="el-upload__tip text-red">2.请上传大小不超过{{ fileSize }}MB, 格式为{{ fileType.join("/") }}</div>
    </template>
  </el-upload>
</template>

<script setup lang="ts">
import { ref, computed, watch, defineProps, defineEmits, defineExpose } from 'vue';
import { genFileId, ElMessage, ElLoading } from 'element-plus';
import type { UploadInstance, UploadProps, UploadRawFile, UploadUserFile, UploadRequestOptions } from 'element-plus';
import { getToken } from '@/utils/auth';
import { fa } from 'element-plus/es/locales.mjs';
const baseUrl = import.meta.env.VITE_APP_BASE_API;
const uploadImgUrl = ref(baseUrl + "/common/upload"); // 上传的图片服务器地址
const headers = ref({ Authorization: "Bearer " + getToken()});
const upload = ref<UploadInstance>()
const fileList = ref<UploadUserFile[]>([])
const loading = ref<any>();
interface chooseFileInteg{
  name: string,
  url: any,
  loading: boolean
}
const chooseFileList = ref<chooseFileInteg[]>([])
const props = defineProps({
  modelValue: [String, Object, Array],
  // 大小限制(MB)
  fileSize: {
    type: Number,
    default: 5,
  },
  // 文件类型, 例如['png', 'jpg', 'jpeg']
  fileType: {
    type: Array,
    default: () => ["png", "jpg", "jpeg"],
  },
  // 是否显示提示
  isShowTip: {
    type: Boolean,
    default: true,
  },
  imgText: {
    type: String,
    default: '点击上传'
  },
  bg: {
    type: String,
    default: 'var(--el-fill-color-lighter)'
  }
})
const emit = defineEmits();
watch(()=>props.modelValue, val=>{
  if(val){
    if(val.indexOf('http') != -1){
      let arr = [{
        name: String(val),
        url: String(val)
      }]
      chooseFileList.value = arr;
      fileList.value = arr;
    }else{
      let arr = [{
        name: baseUrl + val,
        url: baseUrl + val
      }]
      chooseFileList.value = arr;
      fileList.value = arr;
    }
    return val
  }else{
    chooseFileList.value = [];
    fileList.value = [];
    return ''
  }
},{ deep: true, immediate: true })
const showTip = computed(
  () => props.isShowTip && (props.fileType || props.fileSize)
);
const handleBeforeUpload: UploadProps['beforeUpload'] = (file)=>{
  let isImg = false;
  if (props.fileType.length) {
    let fileExtension = "";
    if (file.name.lastIndexOf(".") > -1) {
      fileExtension = file.name.slice(file.name.lastIndexOf(".") + 1);
    }
    isImg = props.fileType.some((type) => {
      if (file.type.indexOf(type) > -1) return true;
      if (fileExtension && fileExtension.indexOf(type) > -1) return true;
      return false;
    });
  } else {
    isImg = file.type.indexOf("image") > -1;
  }
  if (!isImg) {
    ElMessage.error(`文件格式不正确, 请上传${props.fileType.join("/")}图片格式文件!`)
    return false;
  }
  if (props.fileSize) {
    const isLt = file.size / 1024 / 1024 < props.fileSize;
    if (!isLt) {
      ElMessage.error(`上传头像图片大小不能超过 ${props.fileSize} MB!`)
      return false;
    }
  }
  chooseFileList.value[0].loading = true;
}
const handleExceed: UploadProps['onExceed'] = (files) => {
  upload.value!.clearFiles()
  const file = files[0] as UploadRawFile
  file.uid = genFileId()
  upload.value!.handleStart(file)
  upload.value!.submit();
}

const handleChange: UploadProps['onChange'] = (file) =>{
  let url = file?.raw;
  if(url){
    chooseFileList.value = [{
      name: file.name,
      url: URL.createObjectURL(url),
      loading: false
    }]
  }else{
    chooseFileList.value = [{
      name: file.name,
      url: file.url,
      loading: false
    }]
  }
}

const uploadImgNow = ()=>{
  if(fileList.value.length){
    upload.value!.submit()
  }
}

const handleSuccess: UploadProps['onSuccess'] = (res, file)=>{
  chooseFileList.value[0].loading = false;
  if (res.code === 200) {
    emit("update:modelValue", res.fileName);
  } else {
    ElMessage.error(res.msg);
    upload.value!.handleRemove(file);
    emit("update:modelValue", '');
  }
}
const handleError: UploadProps['onError'] = ()=>{
  chooseFileList.value[0].loading = false;
  ElMessage.error('上传图片失败');
}
defineExpose({
  uploadImgNow
})
</script>
<style scoped lang="scss">
@import "@/assets/styles/public.scss";
// .el-upload--picture-card 控制加号部分
:deep(.hide .el-upload--picture-card) {
  display: none;
}
:deep(.el-upload){
    box-sizing: border-box;
    border: 1px dashed #E5E6EB;
    &:focus{
        color: var(--el-color-primary);
        border: 1px dashed var(--el-color-primary);
        .text{
            color: var(--el-color-primary);
        }
    }
    &:hover{
        color: var(--el-color-primary);
        border: 1px dashed var(--el-color-primary);
        .text{
            color: var(--el-color-primary);
        }
    }
    &.is-disabled{
      color: $colorText1;
      border: 1px dashed $borderColor;
      .text{
        color: $colorText1;
      }
    }
}
.successBox{
  position: absolute;
  right: -15px;
  top: -6px;
  width: 40px;
  height: 24px;
  background: var(--el-color-success);
  transform: rotate(45deg);
  transition: opacity var(--el-transition-duration);
  color: white;
}
.upload-image{
    width: 148px;
    height: 148px;
    box-sizing: border-box;
    overflow: hidden;
    position: relative;
    .loadingBox{
      position: absolute;
      top: 0;
      left: 0;
      width: 100%;
      height: 100%;
      background-color: rgba($color: #000000, $alpha: 0.3);
      color: white;
      font-size: 14px;
    }
    &.borderImg{
      margin-left: 10px;
      background-color: #FFFFFF;
      border: 1px solid $borderColor;
    }
}
.text{
  height: 22px;
  font-weight: 400;
  font-size: 14px;
  color: $colorText1;
  line-height: 22px;
  margin-top: 14px;
}
.imgBox{
    width: 100%;
    height: 100%;
    border: 1px solid red;
}
</style>
